package com.education.welco.service.impl;

import com.education.common.pojo.AjaxResult;
import com.education.common.utils.Convert;
import com.education.utils.FileUtils;
import com.education.welco.enums.FileTypeEnum;
import com.education.welco.mapper.PlatResourceShareMapper;
import com.education.welco.mapper.PlatformResourcesMapper;
import com.education.welco.pojo.PlatResourceShare;
import com.education.welco.pojo.PlatformResources;
import com.education.welco.pojo.SResources;
import com.education.welco.pojo.UserStar;
import com.education.welco.pojo.dto.FileUploadDTO;
import com.education.welco.pojo.vo.DirTreeNode;
import com.education.welco.pojo.vo.PathNodeVO;
import com.education.welco.service.IPlatformResourcesService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 平台资源 服务层实现
 *
 * @Author: liftsail
 * @Date: 2022-09-14
 * @Description: 不积跬步无以至千里
 */
@Service
public class PlatformResourcesServiceImpl implements IPlatformResourcesService {

    @Autowired
    private PlatformResourcesMapper platformResourcesMapper;
    @Autowired
    private PlatResourceShareMapper platResourceShareMapper;

    /**
     * 查询平台资源信息
     *
     * @param id 平台资源ID
     * @return 平台资源信息
     */
    @Override
    public PlatformResources selectPlatformResourcesById(Integer id) {
        return platformResourcesMapper.selectPlatformResourcesById(id);
    }

    /**
     * 查询平台资源列表
     *
     * @param platformResources 平台资源信息
     * @return 平台资源集合
     */
    @Override
    public List<PlatformResources> selectPlatformResourcesList(PlatformResources platformResources) {
        return platformResourcesMapper.selectPlatformResourcesList(platformResources);
    }

    /**
     * 新增平台资源
     *
     * @param platformResources 平台资源信息
     * @return 结果
     */
    @Override
    public int insertPlatformResources(PlatformResources platformResources) {
        return platformResourcesMapper.insertPlatformResources(platformResources);
    }

    /**
     * 修改平台资源
     *
     * @param platformResources 平台资源信息
     * @return 结果
     */
    @Override
    public int updatePlatformResources(PlatformResources platformResources) {
        return platformResourcesMapper.updatePlatformResources(platformResources);
    }

    /**
     * 删除平台资源对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deletePlatformResourcesByIds(String ids) {
        return platformResourcesMapper.deletePlatformResourcesByIds(Convert.toStrArray(ids));
    }

    @Override
    public void mkdir(Long userId, String pid, String name) {
        PlatformResources platformResources = new PlatformResources(userId, name, pid);
        platformResourcesMapper.insertPlatformResources(platformResources);
    }

    @Override
    public void mkFile(FileUploadDTO fileUploadDTO) {
        //Long userId, String fileName, String extension, String pid, Long fileSize, String fileUrl
        PlatformResources platformResources = new PlatformResources(fileUploadDTO.getUserId(),
                fileUploadDTO.getFileName(), fileUploadDTO.getExtension(), fileUploadDTO.getPid(),
                fileUploadDTO.getFileSize(), fileUploadDTO.getFileUrl());
        platformResourcesMapper.insertPlatformResources(platformResources);
    }

    @Override
    public PageInfo<PlatformResources> listTheDir(Long userId, String pid, Integer pageNum, Integer pageSize) {
        PlatformResources platformResources = new PlatformResources();
        platformResources.setUserId(userId);
        platformResources.setPid(pid);
        if (pageNum != null && pageSize != null) {
            PageHelper.startPage(pageNum, pageSize);
        }
        List<PlatformResources> platformResourcesList = platformResourcesMapper.selectPlatformResourcesListForListDir(platformResources);
        PageInfo<PlatformResources> platformResourcesPageInfo = new PageInfo<>(platformResourcesList);
        return platformResourcesPageInfo;
    }

    @Override
    public PageInfo<PlatformResources> searchFile(String fileName, Long userId, Integer pageNum, Integer pageSize) {
        PlatformResources platformResources = new PlatformResources();
        platformResources.setFileName(fileName);
        platformResources.setUserId(userId);
        PageHelper.startPage(pageNum, pageSize);
        List<PlatformResources> platformResourcesList = platformResourcesMapper.selectPlatformResourcesListForSearch(platformResources);
        PageInfo<PlatformResources> platformResourcesPageInfo = new PageInfo<>(platformResourcesList);
        return platformResourcesPageInfo;
    }

    @Override
    public PageInfo<PlatformResources> listTheTypeFile(Long userId, FileTypeEnum fileType, Integer pageNum, Integer pageSize) {
        Set<String> extensions = FileUtils.getFileExtensionsByType(fileType);
        //某种类型与其他类型
        List<PlatformResources> platformResourcesList = null;
        if (FileTypeEnum.OTHER == fileType) {
            PageHelper.startPage(pageNum, pageSize);
            platformResourcesList = platformResourcesMapper.selectPlatformResourcesListForListTheTypeFile(userId, extensions, 0);
        } else {
            if (pageNum != null && pageSize != null) {
                PageHelper.startPage(pageNum, pageSize);
            }
            platformResourcesList = platformResourcesMapper.selectPlatformResourcesListForListTheTypeFile(userId, extensions, 1);
        }
        PageInfo<PlatformResources> platformResourcesPageInfo = new PageInfo<>(platformResourcesList);
        return platformResourcesPageInfo;
    }


    @Override
    public DirTreeNode dirTree(Long userId) {
        List<PlatformResources> userFileList = platformResourcesMapper.findAllByUserIdAndDirAndDelete(userId, true, false);

        DirTreeNode rootNode = DirTreeNode.root();

        rootNode.setChildren(
                userFileList.parallelStream().filter(uf -> Objects.isNull(uf.getPid())).map(uf ->
                        DirTreeNode.create(uf, 1L, getDirChildrenTree(uf.getId(), 2L, userFileList))
                ).collect(Collectors.toList())
        );
        return rootNode;

    }

    /**
     * 移动文件
     */
    @Override
    public AjaxResult move(String from, String to) {
        //确认目标文件夹是否有效
        if (Objects.nonNull(to)) {
            PlatformResources toFile = platformResourcesMapper.findByIdAndDelete(to, false);
            if (!toFile.getIsDir()) {
                return AjaxResult.error("目标文件夹不存在或者不是一个文件夹！");
            }
        }
        if (from.equals(to)) {
            //log.warn("移动文件与目标文件夹相同, [{}->{}]", from, to);
            return AjaxResult.error("移动文件与目标文件夹相同！");
        }
        PlatformResources fromFile = platformResourcesMapper.findByIdAndDelete(from, false);
        fromFile.setPid(to);
        int i = platformResourcesMapper.updatePlatformResources(fromFile);
        if (i == 1) {
            return AjaxResult.error("移动成功！");
        }
        return AjaxResult.error("移动失败！");
    }

    @Override
    public AjaxResult move(List<String> fromList, String to) {
        //确认目标文件夹是否有效
        if (Objects.nonNull(to)) {
            PlatformResources toFile = platformResourcesMapper.findByIdAndDelete(to, false);
            if (!toFile.getIsDir()) {
                return AjaxResult.error("目标文件夹不存在或者不是一个文件夹！");
            }
        }
        if (fromList.contains(to)) {
            //log.warn("移动文件与目标文件夹相同, [{}->{}]", fromList, to);
            return AjaxResult.error("存在移动文件与目标文件夹相同！");
        }
        int i = platformResourcesMapper.updatePidByIdInAndPid(fromList, to);
        if (i != 0) {
            return AjaxResult.error("移动成功！");
        }
        return AjaxResult.error("移动失败！");
    }

    /**
     * @param fileId    文件id
     * @param filename  文件基础名
     * @param extension 文件扩展名
     */
    @Override
    public int rename(String fileId, String filename, String extension) {
        PlatformResources platformResources = new PlatformResources();
        platformResources.setId(fileId);
        platformResources.setFileName(filename);
        platformResources.setExtension(extension);
        return platformResourcesMapper.updatePlatformResources(platformResources);
    }

    /**
     * 文件设置备注名称
     *
     * @param fileId     文件id
     * @param fileRemark 文件备注名称
     * @return
     */
    @Override
    public int remark(String fileId, String fileRemark) {
        PlatformResources platformResources = new PlatformResources();
        platformResources.setId(fileId);
        platformResources.setRemark(fileRemark);
        return platformResourcesMapper.updatePlatformResources(platformResources);
    }


    /**
     * 文件批量设置备注名称
     *
     * @param fileIdList 文件id集合
     * @param fileRemark 文件备注名称
     * @return
     */
    @Override
    public int remark(List<String> fileIdList, String fileRemark) {
        return platformResourcesMapper.updateRemarkByIds(fileIdList, fileRemark);
    }


    /**
     * 递归获取子目录
     *
     * @param pid
     * @param depth
     * @param userFileList
     * @return
     */
    private List<DirTreeNode> getDirChildrenTree(String pid, Long depth, List<PlatformResources> userFileList) {

        return userFileList.parallelStream().filter(uf -> pid.equals(uf.getPid())).map(uf ->
                DirTreeNode.create(uf, depth, getDirChildrenTree(uf.getId(), depth + 1, userFileList))
        ).collect(Collectors.toList());
    }


    /**
     * 删除文件或者文件夹，删除文件夹时，文件夹里的文件也一并删除。此操作为逻辑删除
     *
     * @param id 文件id
     */
    @Override
    public void delete(String id) {
        deleteOrRecover(new ArrayList() {{
            add(id);
        }}, true);
        platResourceShareMapper.deletePlatResourceShareByResId(id);
    }

    /**
     * 批量删除
     *
     * @param ids
     */
    @Override
    public void delete(List<String> ids) {
        deleteOrRecover(ids, true);
    }

    /**
     * 批量删除或恢复文件
     *
     * @param idList 文件或目录id列表
     * @param delete 删除文件true-1, 恢复文件false-0
     */
    private void deleteOrRecover(List<String> idList, Boolean delete) {
        List<PlatformResources> childrenList = getChildrenList(idList, !delete);
        //userStorageService.deleteFileCalculator(childrenList, delete);//删除文件计算内存
        platformResourcesMapper.updateDeleteByIdIn(childrenList.stream().map(PlatformResources::getId).collect(Collectors.toList()), delete);
    }

    /**
     * 获取这些文件或者目录及子文件、子目录
     *
     * @param userFileIdList
     * @param delete         如果是获取回收站文件及子文件true，获取非回收站文件false
     * @return
     */
    @Override
    public List<PlatformResources> getChildrenList(List<String> userFileIdList, Boolean delete) {

        List<PlatformResources> userFileList = platformResourcesMapper.findAllByIdInAndDelete(userFileIdList, delete);
        List<PlatformResources> result = new LinkedList<>(userFileList);//返回结果

        userFileList.forEach(userFileEntity -> {
            if (userFileEntity.getIsDir()) {
                List<String> tmpIds = new ArrayList() {{
                    add(userFileEntity.getId());
                }};
                while (!CollectionUtils.isEmpty(tmpIds)) {
                    List<PlatformResources> children = platformResourcesMapper.findAllByPidInAndDelete(tmpIds, delete);
                    tmpIds = children.parallelStream().map(PlatformResources::getId).collect(Collectors.toList());
                    result.addAll(children);
                }
            }
        });
        return result;
    }

    @Override
    public Map<String, PathNodeVO> getPathTreeMap(Long userId) {
        List<PathNodeVO> pathNodeVOList = platformResourcesMapper.findAllPathNodeByUserId(userId);
        Map<String, PathNodeVO> collect = pathNodeVOList.stream().collect(Collectors.toMap(PathNodeVO::getId, PathNodeVO::self));
        return collect;
    }

    @Override
    public Map<String, PathNodeVO> getPathTreeForSchooolRes(Long userId, Integer schoolId) {
        List<PathNodeVO> pathNodeVOList = platformResourcesMapper.findAllPathNodeByUserId(userId);
        Map<String, PathNodeVO> collect = pathNodeVOList.stream().collect(Collectors.toMap(PathNodeVO::getId, PathNodeVO::self));
        PlatResourceShare platResourceShare = new PlatResourceShare();
        platResourceShare.setReceiverId(schoolId);
        platResourceShare.setIsDelete(false);
        List<PlatResourceShare> platResourceShareList = platResourceShareMapper.selectPlatResourceShareList(platResourceShare);
        if (platResourceShareList.size() == 0) {
            return collect;
        }
        List<String> resShareCollect = platResourceShareList.stream().map(a -> a.getResId()).collect(Collectors.toList());
        Map<String, PathNodeVO> collect1 = pathNodeVOList.stream().filter(a -> !resShareCollect.contains(a.getId())).collect(Collectors.toMap(PathNodeVO::getId, PathNodeVO::self));
        Map<String, PathNodeVO> collect2 = pathNodeVOList.stream().filter(a -> resShareCollect.contains(a.getId())).collect(Collectors.toMap(PathNodeVO::getId, PathNodeVO::selfPidBlack));
        collect1.putAll(collect2);
        return collect1;
    }

    @Override
    public PageInfo<PlatformResources> listTheDirForStarList(UserStar userStar, Integer pageNum, Integer pageSize) {
        PlatformResources platformResources = new PlatformResources();
        platformResources.setUserId(Long.valueOf(userStar.getUserId()));
        //platformResources.setPid(null);
        PageHelper.startPage(pageNum, pageSize);
        List<PlatformResources> platformResourcesList = platformResourcesMapper.selectPlatformResourcesListForListDirAndStarList(platformResources);
        PageInfo<PlatformResources> platformResourcesPageInfo = new PageInfo<>(platformResourcesList);
        return platformResourcesPageInfo;
    }

    @Override
    public int updatePlatformResourcesByIdListForShareState(List<String> sharedResId, boolean shareState) {
        //父子级别
        List<PlatformResources> childrenList = getChildrenList(sharedResId, false);
        List<String> idChildrenList = childrenList.stream().map(platformResources -> platformResources.getId()).collect(Collectors.toList());
        return platformResourcesMapper.updatePlatformResourcesByIdListForShareState(idChildrenList, shareState);
    }

    @Override
    public List<PlatformResources> selectShareSchoolResListBySchoolIdAndFileName(Integer teaId, List<String> ridCollect, String fileName, Set<String> extensionSet, Boolean inOrNot, Integer pageNum, Integer pageSize) {
        //父子级别
        if (ridCollect != null && ridCollect.size() == 0) {
            return null;
        }
        List<PlatformResources> childrenList = getChildrenList(ridCollect, false);
        List<String> ridALLCollect = childrenList.stream().map(platformResources -> platformResources.getId()).collect(Collectors.toList());
        if (pageNum != null && pageSize != null) {
            PageHelper.startPage(pageNum, pageSize);
        }
        return platformResourcesMapper.selectShareSchoolResListBySchoolIdAndFileName(teaId, ridALLCollect, fileName, extensionSet, inOrNot);
    }

    @Override
    public List<PlatformResources> listTheDirByNameAndType(Long userId, String fileName, Set<String> extensionSet, Boolean inOrNot, String pid, Integer pageNum, Integer pageSize) {
        if (pageNum != null && pageSize != null) {
            PageHelper.startPage(pageNum, pageSize);
        }
        return platformResourcesMapper.listTheDirByNameAndType(userId, null, fileName, extensionSet, inOrNot, pid);
    }

    /**
     * 通过id集合查询详细信息
     *
     * @param selectedIdList
     * @return
     */
    @Override
    public List<SResources> queryResInfoListByIdList(List<String> selectedIdList) {
        return platformResourcesMapper.queryResInfoListByIdList(selectedIdList);
    }
}